# -*- coding: utf-8 -*-
"""
@Time： 2023/12/20 16:30
@Auth： gubei
@File：response.py
@IDE：PyCharm
@Description：响应类
"""

from typing import Any, Optional, TypeVar, Dict, List, Union, Generic
from fastapi import HTTPException, status
from pydantic import BaseModel

T = TypeVar('T')

class PaginationInfo(BaseModel):
    """分页信息模型"""
    total: int
    page: int
    page_size: int
    pages: int

class ResponseModel(BaseModel, Generic[T]):
    """标准响应模型"""
    code: int
    msg: str
    data: Optional[T] = None
    pagination: Optional[PaginationInfo] = None
    total: Optional[int] = None
    
class R(object):
    """统一响应格式工具类"""

    @staticmethod
    def suc(data: Optional[T] = None, msg: str = "SUCCESS", total: Optional[int] = None, code: int = 200) -> Dict:
        """成功响应
        
        Args:
            data: 响应数据
            msg: 响应消息
            total: 数据总数（用于分页）
            code: 响应状态码
            
        Returns:
            包含响应信息的字典
        """
        content = {
            'code': code,
            'msg': msg,
        }
        if data is not None:
            content['data'] = data
        if total is not None:
            content['total'] = total
        return content

    @staticmethod
    def err(data: Optional[Any] = None, msg: str = "BAD REQUEST", code: int = 400) -> Dict:
        """错误响应
        
        Args:
            data: 错误数据
            msg: 错误消息
            code: 错误状态码
            
        Returns:
            包含错误信息的字典
        """
        content = {
            'code': code,
            'msg': msg,
        }
        if data is not None:
            content['data'] = data
        return content
    
    @staticmethod
    def forbidden(msg: str = "FORBIDDEN", data: Optional[Any] = None) -> Dict:
        """禁止访问响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含403错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_403_FORBIDDEN)
    
    @staticmethod
    def not_found(msg: str = "NOT FOUND", data: Optional[Any] = None) -> Dict:
        """资源未找到响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含404错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_404_NOT_FOUND)
    
    @staticmethod
    def unauthorized(msg: str = "UNAUTHORIZED", data: Optional[Any] = None) -> Dict:
        """未授权响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含401错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_401_UNAUTHORIZED)
    
    @staticmethod
    def server_error(msg: str = "INTERNAL SERVER ERROR", data: Optional[Any] = None) -> Dict:
        """服务器错误响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含500错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @staticmethod
    def bad_request(msg: str = "BAD REQUEST", data: Optional[Any] = None) -> Dict:
        """错误请求响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含400错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_400_BAD_REQUEST)
    
    @staticmethod
    def conflict(msg: str = "CONFLICT", data: Optional[Any] = None) -> Dict:
        """资源冲突响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含409错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_409_CONFLICT)
        
    @staticmethod
    def validation_error(msg: str = "VALIDATION ERROR", data: Optional[Any] = None) -> Dict:
        """数据验证错误响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含422错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_422_UNPROCESSABLE_ENTITY)
    
    @staticmethod
    def too_many_requests(msg: str = "TOO MANY REQUESTS", data: Optional[Any] = None) -> Dict:
        """请求过多响应
        
        Args:
            msg: 错误消息
            data: 错误数据
            
        Returns:
            包含429错误信息的字典
        """
        return R.err(data=data, msg=msg, code=status.HTTP_429_TOO_MANY_REQUESTS)
    
    @staticmethod
    def raise_err(msg: str = "BAD REQUEST", code: int = 400, headers: Optional[Dict[str, str]] = None):
        """抛出HTTP异常
        
        Args:
            msg: 错误消息
            code: 错误状态码
            headers: 额外的响应头
            
        Raises:
            HTTPException: 包含指定错误信息的HTTP异常
        """
        raise HTTPException(status_code=code, detail=msg, headers=headers)
    
    @staticmethod
    def paginate(data: List[T], total: int, page: int, page_size: int) -> Dict:
        """分页响应
        
        Args:
            data: 分页数据
            total: 数据总数
            page: 当前页码
            page_size: 每页大小
            
        Returns:
            包含分页信息的字典
        """
        return {
            'code': 200,
            'msg': 'SUCCESS',
            'data': data,
            'pagination': {
                'total': total,
                'page': page,
                'page_size': page_size,
                'pages': (total + page_size - 1) // page_size
            }
        }

    @staticmethod
    def no_content() -> Dict:
        """没有内容响应
        
        Returns:
            包含204状态码的空响应
        """
        return {
            'code': status.HTTP_204_NO_CONTENT,
            'msg': 'NO CONTENT',
            'data': None
        }
        
    @staticmethod
    def created(data: Optional[T] = None, msg: str = "CREATED") -> Dict:
        """资源创建成功响应
        
        Args:
            data: 创建的资源数据
            msg: 响应消息
            
        Returns:
            包含201状态码的响应
        """
        return R.suc(data=data, msg=msg, code=status.HTTP_201_CREATED)
